home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_200
/
298_01
/
demo.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-06-05
|
10KB
|
374 lines
/* PC Curses. (C) Copyright 1987 Jeffrey S. Dean. All Rights Reserved. */
/* demo - simple program to demonstrate curses
*
* The purpose of this program is to demonstrate PC Curses.
* It provides a working example of what PC Curses looks like
* when running; it also provides examples of how to write code
* using the PC Curses package (for those who might not be
* familiar with it).
*
* brief outline:
* reads in a data file, containing short paragraphs separated
* by formfeeds; there can be no more than COUNT paragraphs.
* each paragraph is put in a window, and then the user hits
* <return> to sequence through the windows.
*
* functions:
* main
* fillwin - fills window with data from a file
* changemode - toggles between bios and direct screen updates
* changerefresh - toggles between wrefresh() and wnoutrefresh()
* help - displays a help screen
* message - places message in prompt window
*/
/* the standard include file for curses */
#include <curses.h>
/* if working on unix, use this special include file
* for extended or non-standard PC Curses things
*/
#ifdef unix
#include "unix.h"
#endif
/* the data file */
#define DEMODATA "demo.dat"
/* the help file */
#define HELPFILE "demo.hlp"
/* maximum of windows */
#define COUNT 10
/* size of each window */
#define NUMCOLS 60
#define NUMROWS 11
/* an array of window pointers */
WINDOW *winlist[COUNT];
/* the last window in winlist */
int last;
/* coordinates of first window */
#define YFIRST 2
#define XFIRST 2
/* flag to use wnoutrefresh instead of wrefresh */
int norefresh = 0;
/* window for the prompt message */
WINDOW *promptwin;
/* the prompt message */
char prompt[] =
" <RETURN> for next, <BACKSPACE> for previous, F1 for help \n";
main()
{
int i, j, cmd;
FILE *demofile;
/** standard curses initialization **/
if( ERR == initscr() ) {
fprintf(stderr, "cannot initialize screen!\n");
exit(1);
}
/* set up function key translation */
keypad(stdscr, TRUE);
/* raw mode means we get to handle ^C etc. */
raw();
/* do not automatically echo user's input */
noecho();
/* nonl() is mainly for Unix compatibility */
nonl();
/* set up the prompt window */
if( NULL == (promptwin = newwin(1, sizeof(prompt), LINES-1, 10)) ) {
fprintf(stderr, "cannot open prompt window\n");
endwin();
exit(1);
}
else wstandout(promptwin);
message(prompt);
/* setting leaveok turns off the cursor in the window */
leaveok(promptwin, TRUE);
leaveok(curscr, TRUE);
/* set up the demo data file */
demofile = fopen(DEMODATA, "r");
if( demofile == NULL ) {
perror(DEMODATA);
exit(1);
}
/* we now create and fill up windows from the demo data file */
for( i = 0; i < COUNT; i++ ) {
/* allocate a new window */
winlist[i] = newwin(NUMROWS, NUMCOLS,
YFIRST + i, XFIRST + 2*i);
if( winlist[i] == NULL ) {
fprintf(stderr, "cannot open window #%d\n", i);
endwin();
exit(1);
}
/* draw a double box around it */
box(winlist[i], D_VERT, D_HOR);
/* and break if no more data */
if( fillwin(demofile, winlist[i]) == 0 ) break;
}
fclose(demofile);
last = i-1;
/* up to this point, windows have been filled but
* none have been displayed. now display them,
* layered on top of each other, starting with
* the last and working up to the first.
*
* Note that refresh here is more complicated than it will
* normally be in an application, since we handle two kinds
* of refreshing (termcap-style and terminfo-style), based
* on the norefresh flag.
*/
for( i = last; i >= 0; i-- ) {
if( norefresh ) wnoutrefresh(winlist[i]);
else wrefresh(winlist[i]);
}
if( norefresh ) doupdate();
/* sequence through the windows */
for( i = 0; i <= last; ) {
/* draw highlighted box around the top window
* note that we are boxing with both single and horizontal
* lines; box() is smart enough to choose the right
* corner characters.
*/
box(winlist[i], A_REVERSE|S_VERT, A_REVERSE|D_HOR);
/* refresh current window (pop it to the top) */
if( norefresh ) wnoutrefresh(winlist[i]);
else wrefresh(winlist[i]);
/* display whatever is on the prompt line */
wrefresh(promptwin);
/* and wait for user input */
cmd = getch();
/* restore normal (unhighlighted) box */
box(winlist[i], S_VERT, D_HOR);
if( norefresh ) wnoutrefresh(winlist[i]);
else wrefresh(winlist[i]);
/* process user's command
* this is an example of a typical curses command loop
*/
switch(cmd) {
case KEY_UP:
case KEY_LEFT:
case '\b': /* backspace goes back one window */
if( i > 0 ) i--;
break;
case KEY_DOWN:
case KEY_RIGHT:
case '\r': /* return goes forward one window */
case '\n':
i++;
break;
case '\002': /* control-b toggle bios updating */
changemode();
break;
case '\003': /* control-c aborts */
endwin();
exit(1);
case '\007': /* control-g flashes */
beep();
flash();
break;
case '\f': /* formfeed redisplays the screen */
/* fix the prompt line */
message(prompt);
/* clear the screen */
wclear(curscr);
/* redisplay to get to initial state */
for( j = last; j >= 0; j-- ) {
touchwin(winlist[j]);
if( norefresh )
wnoutrefresh(winlist[j]);
else wrefresh(winlist[j]);
}
/* move back down to current window */
for( j = 0; j < i; j++ ) {
touchwin(winlist[j]);
if( norefresh )
wnoutrefresh(winlist[j]);
else wrefresh(winlist[j]);
}
break;
case '\027': /* control-w toggles refresh mode */
changerefresh();
break;
case KEY_F(1):
help(HELPFILE);
break;
default:
message(prompt);
break;
}
}
/** normal procedure for exiting curses **/
/* clear the screen */
clear();
refresh();
/* tell curses we are done */
endwin();
exit(0);
}
int scradr = T_BIOS;
/* changemode - change screen update mode */
changemode()
{
char buf[80];
if( scradr == T_BIOS ) {
sprintf(buf, "Screen update method: DIRECT (at 0x%4.4X)",
scradr = pc_uptype(T_DIRECT) );
}
else {
scradr = pc_uptype(T_BIOS);
strcpy(buf, " Screen update method: BIOS");
}
message(buf);
}
/* changerefresh - change refresh method
*
* old style of refresh is to use wrefresh;
* new style of refresh is to use wnoutrefresh, then
* doupdate() after all change have been made, resulting
* in just one screen update.
*/
changerefresh()
{
norefresh = !norefresh;
if( norefresh )
message("Using new style (wnoutrefresh/doupdate) updating");
else
message("Using old style (wrefresh) updating");
}
/* message - display message in the prompt window */
message(str)
char *str;
{
wmove(promptwin, 0, 0);
wclrtoeol(promptwin);
wmove(promptwin, 0, 1);
waddstr(promptwin, str);
}
/** the following two functions, help() and fillwin(), are general
* purpose routines. help displays a help window; fillwin fills
* a window from a file, interpreting control characters as attributes.
*
* Usage:
* help(filename)
* char *filename;
* returns OK if successful, ERR otherwise.
* In this version, the filename is only used the first time
* through; subsequent calls just use the same data.
* An error return is possible only on the first call, and
* indicates a problem with the help file or a memory shortage.
*
* The help window disappears when any key is pressed.
*
* fillwin(f, win);
* FILE *f; WINDOW *win;
* returns 0 on EOF, 1 otherwise
* Reads data until a formfeed, puts data into window. Several
* control characters are allowed; their occurrence in the file
* causes fillwin to modify attributes. The valid characters are:
* ^B - bold
* ^F - flash
* ^N - normal
* ^R - reverse
* ^U - underline
*/
help(file)
char *file;
{
static WINDOW *helpwin = NULL, *shadow;
static int stat = OK;
FILE *f;
if( stat == ERR ) return(ERR);
if( helpwin == NULL ) {